﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Documents;

namespace SHomeWorkshop.LunarPresentation.Dialogs
{
    /// <summary>
    /// LoadExFromOutportedExImageDlg.xaml 的交互逻辑
    /// </summary>
    public partial class LoadExFromOutportedExImageDlg : Window
    {
        public LoadExFromOutportedExImageDlg()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            if (this.Owner != null)
            {
                this.Owner.Visibility = Visibility.Hidden;
            }
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            if (this.Owner != null && this.Owner.Visibility == Visibility.Hidden)
            {
                this.Owner.Visibility = Visibility.Visible;
            }
        }

        private void cvReceiver_Drop(object sender, DragEventArgs e)
        {
            //检验放在调用时。在D:\My Documents\Visual Studio 2010\Projects\LunarPresentation\LunarPresentation\MainWindow.xaml.cs
            //中的miTryLoadExFromOutportedExImage_Click()方法头部。

            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                Array dragDataArray = ((System.Array)e.Data.GetData(DataFormats.FileDrop));

                if (dragDataArray.Length <= 0)
                {
                    e.Handled = true;
                    MessageBox.Show("此处只能接收以前导出的某个png的公式图！", Globals.appName,
                        MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }
                else if (dragDataArray.Length > 1)
                {
                    e.Handled = true;
                    MessageBox.Show("此处只能接收以前导出的某个png的公式图！不能接收多个文件。", Globals.appName,
                        MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }

                List<string> filenames = new List<string>();

                foreach (string s in dragDataArray)
                {
                    filenames.Add(s);
                }

                string filename = filenames[0];

                if (filenames[0].EndsWith(".png") == false)
                {
                    e.Handled = true;
                    MessageBox.Show("此处只能接收以前导出的某个png的公式图！不能接收其它格式的文件。\r\n\r\n" +
                        "请注意：导出的tiff格式的公式图像中是不包括附加信息的，因而不能尝试恢复！",
                        Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }

                //尝试从此文件中读取出公式的Xml文本。

                StringBuilder sb = TryReadXmlFromPngOutportedExImage(filename);

                if (sb == null) return;//在TryReadXmlFromPngOutportedExImage()方法中已显示了相关消息框。

                if (sb.Length <= 0)
                {
                    e.Handled = true;
                    MessageBox.Show("这个PNG文件可能不是由本程序导出的图片文件，" +
                        "或者此图片中的附加信息已被破坏，无法从中获取文档内容。\r\n\r\n" +
                        "使用图像编辑软件编辑并保存导出的公式图会破坏附加的公式文本信息。",
                        Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }

                TryLoadExFromXml(Globals.selectedEditor.SelectedExpression, sb.ToString());

                e.Handled = true;
                this.Close();
            }
            else
            {
                e.Handled = true;
                MessageBox.Show("此处只能接收以前导出的某个png的公式图！不能接收其它格式的文件。\r\n\r\n" +
                    "请注意：导出的tiff格式的公式图像中是不包括附加信息的，因而不能尝试恢复！",
                    Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
        }

        private StringBuilder TryReadXmlFromPngOutportedExImage(string filename)
        {
            bool start = false;
            StringBuilder sb = new StringBuilder();
            using (StreamReader sr = File.OpenText(filename))
            {
                string s = "";
                while ((s = sr.ReadLine()) != null)
                {
                    if (start == false)
                    {
                        if (s.EndsWith("<?Lunar Presentation NormalEx?>"))
                        {
                            start = true;
                        }
                        else if (s.EndsWith("<?Lunar Presentation SubPanelEx?>"))
                        {
                            MessageBox.Show("这个PNG文件中附带的公式是个子面板，不是普通公式。暂时不支持恢复到当前公式后侧。",
                                Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                            return null;
                        }
                        else if (s.EndsWith("<?Lunar Presentation?>"))
                        {
                            MessageBox.Show("这个PNG文件可能是根面板（相当于整个文档）的导出图，不是普通公式的导出图。不支持此功能。",
                                Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                            return null;
                        }

                        continue;
                    }

                    sb.Append(s);
                }
            }

            return sb;
        }

        private void TryLoadExFromXml(Expressions.Expression curEx, string exXml)
        {
            if (exXml == null || exXml.Length == 0)
            {
                //如果没有文本，看看是否要粘贴图片框。
                return;
            }

            if (curEx == null) return;

            ModifingItem mi = new ModifingItem() { OldSelectedExID = curEx.ExID };

            if (curEx is Expressions.SubPanel)
            {
                //Expressions.SubPanel subPanel = curEx as Expressions.SubPanel;
                //if (subPanel.BasePanel != null && subPanel.BasePanel.Children.Count > 0 &&
                //    subPanel.BasePanel.Children[0] is Expressions.Expression)
                //{
                //    curEx = subPanel.BasePanel.Children[0] as Expressions.Expression;
                //}
                //else
                //{
                //    System.Windows.MessageBox.Show("子面板中无公式，无法执行粘贴公式操作！",
                //        Globals.appName, System.Windows.MessageBoxButton.OK,
                //        System.Windows.MessageBoxImage.Warning);
                //    return;
                //}

                //由于可能与在子面板末尾的一个折叠的标题文本块冲突，因此禁止在选取子面板的情况下执行此操作。

                return;
            }

            Expressions.Expression newEx = Commands.Command.InsertExpressionByXmlString(false, exXml, curEx);

            #region 看看载入的是不是一个“树”，如果不是，直接递归重建所有公式的ID。

            Expressions.Tree tree = newEx as Expressions.Tree;
            if (tree == null)
            {
                Expressions.Expression.RebuildAllExIDs(newEx);//为避免重复的ExID，重建此公式及子级的所有ExID。
            }
            else
            {
                tree.NewExID(Guid.NewGuid().ToString());//树本身需要一个新的ExID。

                Expressions.Tree.RefreshPreLevelIDs(tree.XmlData.ChildNodes);
                foreach (Expressions.SubPanel sPanel in tree.SubPanels)
                {
                    Expressions.LeafPanel lp = sPanel as Expressions.LeafPanel;

                    if (lp != null)
                    {
                        lp.LoadXmlExID();
                        lp.LoadPreLevelExID();

                        foreach (UIElement ue in lp.BasePanel.Children)
                        {
                            Expressions.Expression ex = ue as Expressions.Expression;

                            if (ex != null)
                            {
                                Expressions.Expression.RebuildAllExIDs(ex);
                            }
                        }
                    }
                }

                tree.RefreshLayout(false);
            }
            #endregion

            Action action = new Action(newEx.ExID, newEx.ParentPanel.BasePanel.Children.IndexOf(newEx),
                newEx.GetType().Name, "InsertExpression", null, newEx.XmlData.OuterXml,
                ActionType.Insert, newEx.ParentPanel.ExID);
            mi.Add(action);

            int newIndex = newEx.ParentPanel.BasePanel.Children.IndexOf(newEx);
            Expressions.Expression preVisibleEx = null;
            for (int i = newIndex - 1; i >= 0; i--)
            {
                Expressions.Expression ex = newEx.ParentPanel.BasePanel.Children[i] as Expressions.Expression;
                if (ex.Visibility == Visibility.Visible)
                {
                    preVisibleEx = ex;
                    break;
                }
            }

            if (preVisibleEx != null && preVisibleEx is Expressions.BaseText)
            {
                Expressions.BaseText preVisibleBt = preVisibleEx as Expressions.BaseText;
                if (preVisibleBt.Indent < newEx.Indent && preVisibleBt.IsCollapsed)
                {
                    Action actUnCollapse = new Action(preVisibleBt.ExID, -1,
                        preVisibleBt.GetType().Name, "IsCollapsed", true.ToString(), false.ToString());

                    preVisibleBt.IsCollapsed = false;

                    mi.Add(actUnCollapse);
                }
            }

            if (newEx is Expressions.BaseText)
            {
                Expressions.BaseText bt = newEx as Expressions.BaseText;
                if (bt.IsHeaderText)
                {
                    newEx.ParentPanel.RefreshAutoNumbersOfBaseText();
                }
            }

            newEx.Editor.Do(mi);
        }
    }
}
